package utils;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateUtils {

    static Calendar tomorrow;
    static Calendar nextHours;
    public static final long ONE_DAY = 86400000L; //Milisengundos del dia
    public static final double MILISEGUNDOS_POR_HORA = 3600000; //Milisegundo en una hora
    public static String DD_MM_YYYY_FORMAT = "dd/MM/yyyy";
    public static String HOUR_FORMAT = "HH:mm";


    public static String formatDate(Date fecha, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.format(fecha);
    }

    public static int CompararFechas(Date fecha1, Date fecha2) {

        if (fecha1.getTime() < fecha2.getTime()) {
            return -1;
        } else if (fecha1.getTime() > fecha2.getTime()) {
            return 1;
        }
        return 0;
    }

    public static boolean isMayorFechaSistema(Date fecha) {
        Calendar sysDate = Calendar.getInstance();
        Calendar toValidate = Calendar.getInstance();
        toValidate.setTime(fecha);

        if (toValidate.getTimeInMillis() > sysDate.getTimeInMillis()) {
            return true;
        }
        return false;
    }

    public static boolean isMenorFechaSistema(Date fecha) {
        Calendar sysDate = Calendar.getInstance();
        Calendar toValidate = Calendar.getInstance();
        toValidate.setTime(fecha);

        if (toValidate.getTimeInMillis() < sysDate.getTimeInMillis()) {
            return true;
        }
        return false;
    }

    public static boolean isTomorrow(Date fecha) {

        Calendar toValidate = Calendar.getInstance();
        toValidate.setTime(fecha);
        tomorrow = Calendar.getInstance();
        tomorrow.add(Calendar.DAY_OF_MONTH, 1);

        if (toValidate.get(Calendar.YEAR) == tomorrow.get(Calendar.YEAR)
                && toValidate.get(Calendar.MONTH) == tomorrow.get(Calendar.MONTH)
                && toValidate.get(Calendar.DAY_OF_MONTH) == tomorrow.get(Calendar.DAY_OF_MONTH)) {
            return true;
        }

        return false;
    }

    /**
     *
     * @param fechaInicial
     * @param fechaFinal
     * @return diferencia en horas
     */
    public static double diferenciaEnHoras(Date fechaInicial, Date fechaFinal) {
        return (fechaFinal.getTime() - fechaInicial.getTime()) / MILISEGUNDOS_POR_HORA;
    }

    public static boolean isInNextNHours(Date fecha, int hHours) {
        Calendar toValidate = Calendar.getInstance();
        toValidate.setTime(fecha);
        nextHours = Calendar.getInstance();
        nextHours.add(Calendar.HOUR_OF_DAY, hHours);

        if (toValidate.get(Calendar.YEAR) == nextHours.get(Calendar.YEAR)
                && toValidate.get(Calendar.MONTH) == nextHours.get(Calendar.MONTH)
                && toValidate.get(Calendar.DAY_OF_MONTH) == nextHours.get(Calendar.DAY_OF_MONTH)
                && toValidate.get(Calendar.HOUR_OF_DAY) == nextHours.get(Calendar.HOUR_OF_DAY)) {
            return true;
        }

        return false;
    }

    public static Integer calcularEdadenAnios(Date fecha) {
        if (fecha == null) {
            return null;
        }
        Calendar a = Calendar.getInstance();
        a.setTime(fecha);
        Calendar b = Calendar.getInstance();
        int age = b.get(Calendar.YEAR) - a.get(Calendar.YEAR);
        if (a.get(Calendar.MONTH) > b.get(Calendar.MONTH) || (a.get(Calendar.MONTH) == b.get(Calendar.MONTH) && a.get(Calendar.DATE) > b.get(Calendar.DATE))) {
            age--;
        }
        return age;
    }

    public static String calcularEdad(Date fechaInicio) {

        if (fechaInicio == null) {
            return null;
        }

        Calendar calendarInicio = Calendar.getInstance();
        calendarInicio.setTime(fechaInicio);
        int diaInicio = calendarInicio.get(Calendar.DAY_OF_MONTH);
        int mesInicio = calendarInicio.get(Calendar.MONTH) + 1; // 0 Enero, 11 Diciembre
        int anioInicio = calendarInicio.get(Calendar.YEAR);

        // Fecha fin
        Calendar calendarFin = Calendar.getInstance();
        int diaFin = calendarFin.get(Calendar.DAY_OF_MONTH);
        int mesFin = calendarFin.get(Calendar.MONTH) + 1; // 0 Enero, 11 Diciembre
        int anioFin = calendarFin.get(Calendar.YEAR);

        //to solve primefaces bug - dates before 1934 are taken as 2034
        if (anioInicio > anioFin) {
            anioInicio -= 100;
            calendarInicio.add(Calendar.YEAR, -100);
        }

        int anios = 0;
        int mesesPorAnio = 0;
        int diasPorMes = 0;
        int diasTipoMes = 0;

        //
        // Calculo de d�as del mes
        //
        if (mesInicio == 2) {
            // Febrero
            if ((anioFin % 4 == 0) && ((anioFin % 100 != 0) || (anioFin % 400 == 0))) {
                // Bisiesto
                diasTipoMes = 29;
            } else {
                // No bisiesto
                diasTipoMes = 28;
            }
        } else if (mesInicio <= 7) {
            // De Enero a Julio los meses pares tienen 30 y los impares 31
            if (mesInicio % 2 == 0) {
                diasTipoMes = 30;
            } else {
                diasTipoMes = 31;
            }
        } else if (mesInicio > 7) {
            // De Julio a Diciembre los meses pares tienen 31 y los impares 30
            if (mesInicio % 2 == 0) {
                diasTipoMes = 31;
            } else {
                diasTipoMes = 30;
            }
        }

        //
        // Calculo de diferencia de a�o, mes y dia
        //
        if ((anioInicio > anioFin) || (anioInicio == anioFin && mesInicio > mesFin)
                || (anioInicio == anioFin && mesInicio == mesFin && diaInicio > diaFin)) {
            // La fecha de inicio es posterior a la fecha fin
            // System.out.println("La fecha de inicio ha de ser anterior a la fecha fin");
            return null;
        } else {
            if (mesInicio <= mesFin) {
                anios = anioFin - anioInicio;
                if (diaInicio <= diaFin) {
                    mesesPorAnio = mesFin - mesInicio;
                    diasPorMes = diaFin - diaInicio;
                } else {
                    if (mesFin == mesInicio) {
                        anios = anios - 1;
                    }
                    mesesPorAnio = (mesFin - mesInicio - 1 + 12) % 12;
                    diasPorMes = diasTipoMes - (diaInicio - diaFin);
                }
            } else {
                anios = anioFin - anioInicio - 1;
                if (diaInicio > diaFin) {
                    mesesPorAnio = mesFin - mesInicio - 1 + 12;
                    diasPorMes = diasTipoMes - (diaInicio - diaFin);
                } else {
                    mesesPorAnio = mesFin - mesInicio + 12;
                    diasPorMes = diaFin - diaInicio;
                }
            }
        }
        return anios + " anos, " + mesesPorAnio + " meses y " + diasPorMes + " dias.";
    }
}
